package com.lean.android.sysinfo

import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Build
import android.provider.Settings
import android.telephony.TelephonyManager
import android.util.Log
import androidx.annotation.RequiresPermission
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader


object OsDataProvider {


    /**
     * Check if device is rooted. Source:
     * https://stackoverflow.com/questions/1101380/determine-if-running-on-a-rooted-device
     */
    fun isDeviceRooted(): Boolean = checkRootMethod1() || checkRootMethod2() || checkRootMethod3()

    private fun checkRootMethod1(): Boolean {
        val buildTags = Build.TAGS
        return buildTags != null && buildTags.contains("test-keys")
    }

    private fun checkRootMethod2(): Boolean {
        val paths = arrayOf(
            "/system/app/Superuser.apk",
            "/sbin/su",
            "/system/bin/su",
            "/system/xbin/su",
            "/data/local/xbin/su",
            "/data/local/bin/su",
            "/system/sd/xbin/su",
            "/system/bin/failsafe/su",
            "/data/local/su"
        )
        return paths.any { File(it).exists() }
    }

    private fun checkRootMethod3(): Boolean {
        var process: Process? = null
        return try {
            process = Runtime.getRuntime().exec(arrayOf("/system/xbin/which", "su"))
            val br = BufferedReader(InputStreamReader(process.inputStream))
            br.readLine() != null
        } catch (t: Throwable) {
            false
        } finally {
            process?.destroy()
        }
    }

    /**
     * Specify if device is using ART or Dalvik
     */
    private fun getVmVersion(): String {
        var vm = "Dalvik"
        val vmVersion = System.getProperty("java.vm.version")
        if (vmVersion != null && vmVersion.startsWith("2")) {
            vm = "ART"
        }
        return vm
    }

    fun isAdbEnabled(context: Context): Boolean {
        return Settings.Secure.getInt(context.contentResolver, Settings.Global.ADB_ENABLED, 0) > 0
    }

    fun hasSimCard(context: Context): Boolean {
        val telManager = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        val simState = telManager.simState
        return simState != TelephonyManager.SIM_STATE_ABSENT && simState != TelephonyManager.SIM_STATE_UNKNOWN
    }

    @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
    fun hasVpn(context: Context): Boolean {
        val connectivityManager =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        val networkInfo = connectivityManager.activeNetwork ?: return false
        val nc = connectivityManager.getNetworkCapabilities(networkInfo) ?: return false
        return nc.hasTransport(NetworkCapabilities.TRANSPORT_VPN)
    }

    fun hasProxy(context: Context): Boolean {
        return try {
            val proxyHost = System.getProperty("http.proxyHost")
            val portStr = System.getProperty("http.proxyPort")
            val proxyPort = if (portStr.isNullOrEmpty()) -1 else portStr.toIntOrNull()
            !proxyHost.isNullOrEmpty() && proxyPort != -1
        } catch (e: Exception) {
            Log.e("Proxy", "get system property failed", e)
            false
        }
    }
}